{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "852c7264-80e5-456c-8443-99d16d55be7b",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "欢迎使用任务代办系统!是否启动？\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入y/n y\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "欢迎进入任务代办系统!\n",
      "请查看功能菜单并选择功能执行:\n",
      "1.添加任务;\n",
      "2.删除任务;\n",
      "3.查看/标记任务;\n",
      "4.查看已删除任务;\n",
      "5.退出程序\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入1-5的数字选择功能:  1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你选择了功能1\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请录入新任务名:  coding\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "是否马上开始新任务?\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入y/n y\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "新增任务完成!\n",
      "请查看功能菜单并选择功能执行:\n",
      "1.添加任务;\n",
      "2.删除任务;\n",
      "3.查看/标记任务;\n",
      "4.查看已删除任务;\n",
      "5.退出程序\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入1-5的数字选择功能:  3\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你选择了功能3\n",
      "请选择要执行的功能: \n",
      "1.查看任务;\n",
      "2.标记任务;\n",
      "3.退出功能\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入你想执行的功能序号:  2\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你选择了功能2\n",
      "1.coding\n",
      "\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入要执行的任务数字序号:  1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "coding\n",
      "coding现在的状态为进行中\n",
      "请选择修改后的状态:\n",
      "1.已完成\n",
      "2.待开始\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "你的选择是:  2\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "状态已更新!\n",
      "请选择要执行的功能: \n",
      "1.查看任务;\n",
      "2.标记任务;\n",
      "3.退出功能\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入你想执行的功能序号:  1\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你选择了功能1\n",
      "请选择要你想要进一步执行的功能: \n",
      "1.查看全部任务;\n",
      "2.查看已完成任务;\n",
      "3.查看进行中的任务;\n",
      "4.查看未开始的任务;\n",
      "5.退出\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入你想进一步执行的功能序号:  4\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你选择了功能4\n",
      "请查看你选取的任务: \n",
      "{'任务名': 'coding', '状态': '待开始'}\n",
      "请选择要你想要进一步执行的功能: \n",
      "1.查看全部任务;\n",
      "2.查看已完成任务;\n",
      "3.查看进行中的任务;\n",
      "4.查看未开始的任务;\n",
      "5.退出\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入你想进一步执行的功能序号:  5\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你选择了功能5\n",
      "感谢!\n",
      "请选择要执行的功能: \n",
      "1.查看任务;\n",
      "2.标记任务;\n",
      "3.退出功能\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入你想执行的功能序号:  3\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你选择了功能3\n",
      "谢谢使用!\n",
      "请查看功能菜单并选择功能执行:\n",
      "1.添加任务;\n",
      "2.删除任务;\n",
      "3.查看/标记任务;\n",
      "4.查看已删除任务;\n",
      "5.退出程序\n"
     ]
    },
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入1-5的数字选择功能:  5\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你选择了功能5\n",
      "感谢使用!\n"
     ]
    }
   ],
   "source": [
    "#代办业务系统\n",
    "tasklist=[]#用于存放新建任务的列表\n",
    "newtask={}#用于临时存放新建任务的字典，将被装入tasklist列表中\n",
    "taskdelete=[]#用于存放已删除人物的列表\n",
    "\n",
    "def y_n(prompt='请输入y/n',valid_choice=['y','n']):#设置选择y/n的模块，有效输入信息为'y'或'n'\n",
    "    while True:#遇到break前将一直执行的循环\n",
    "        choice=input(prompt).strip()#把prompt输入的字符串赋予变量choice\n",
    "        if choice in valid_choice:#如果choice在有效信息内\n",
    "            return choice#把choice代表的输入的有效范围内的字符串结果输出到模块外使用\n",
    "            break#循环结束\n",
    "        else:\n",
    "            print('输入非法!请输入y/n')#如不在有效信息内，要求重新循环执行输入\n",
    "\n",
    "def picktask():#设置给任务名编号、选择、并输出对应选择的任务名的字符串结果的模块\n",
    "    tasknames=[]#用于存放选出的任务名的列表\n",
    "    for task in tasklist:#遍历tasklist列表中的每个元素并称它们为task\n",
    "        n=task['任务名']#每个task实际上都是字典，把task中名为'任务名'的key对应的value(也就是任务的实际名字)赋值给n\n",
    "        tasknames.append(n)#把每个遍历过并被赋值了的n逐一存入tasknames列表\n",
    "\n",
    "    for i,n in enumerate(tasknames):#利用enumerate函数给tasknames列表中的每个任务名字符串编号并遍历\n",
    "        print(f'{i+1}.{n}\\n')#因为默认编号是0，因此打印的编号需要+1\n",
    "    while True:##遇到break前将一直执行的循环\n",
    "        seq_taskname=input('请输入要执行的任务数字序号: ').strip()#输入一个数字序号，这个需要理应在上一步enumerate函数编号遍历并打印的所有编号范围内\n",
    "        if int(seq_taskname) in range(len(tasknames)+1):#把输入的数字序号转化为数字格式并判断是否在tasknames列表的长度+1范围内，+1的原因是，虽然len能取到列表中元素的个数，但range函数不包含最大的数字，因此要+1\n",
    "            break#输入的数字有效后，终止循环\n",
    "        else:\n",
    "            print('非法输入!请重新输入要执行的任务数字序号')#如输入的数字不在有效范围内，要求重新循环执行输入\n",
    "    pickname=tasknames[int(seq_taskname)-1]#把tasknames列表中索引号为int(seq_taskname)-1的元素赋值给变量pickname，其实int(seq_taskname)-1是对上面enumerate函数编号时+1的还原，为了符合字典原本的索引逻辑，而enumerate函数是为了用户视觉舒适逻辑以及后续的选择习惯性逻辑，这一点是人类语言和python语言的众多碰撞之一形成的必然操作\n",
    "    return pickname#把pickname变量代表的经过上述一系列动作选择出来的任务名字符串结果交到模块外使用      \n",
    "\n",
    "def check(status):#设置可以打印不同标记状态的任务清单的模块,其中status为*形式参数*，可以在实际使用模块时用实际参数替换这个形式参数并使用实际参数对应的结果\n",
    "    print('请查看你选取的任务: ')#首先打印提示语\n",
    "    for t in tasklist:#遍历tasklist列表中的所有元素(字典)，把这些字典逐个用变量t代表\n",
    "        if status in t['状态']:#如果形式参数存在于字典t中名为'状态'的key对应的value中(或者我觉得在这里用==也行)时\n",
    "            print(t)#才把符合条件的字典t打印出来\n",
    "#上面这些模块，除了第一个，另外两个都是我在编写程序时才发现设置模块比较好\n",
    "print('欢迎使用任务代办系统!是否启动？')#提示欢迎词\n",
    "choice=y_n(prompt='请输入y/n',valid_choice=['y','n'])#使用选择y/n的模块\n",
    "if choice=='n':\n",
    "    print('谢谢使用,再见!')\n",
    "else:\n",
    "    print('欢迎进入任务代办系统!')#提示语编程欢迎进入，与前面欢迎使用以示区分，表明已经进入了系统内部\n",
    "    while True:#遇到break前将一直循环\n",
    "        print('请查看功能菜单并选择功能执行:')\n",
    "        print('1.添加任务;')\n",
    "        print('2.删除任务;')\n",
    "        print('3.查看/标记任务;')\n",
    "        print('4.查看已删除任务;')\n",
    "        print('5.退出程序')\n",
    "        func_choice=input('请输入1-5的数字选择功能: ').strip()#提示输入功能对应的数字\n",
    "        if func_choice in ['1','2','3','4','5']:#将有效的输入范围确定好，并判断输入数字是否在有效范围内\n",
    "            print(f'你选择了功能{int(func_choice)}')#如果有效则提示用户选择的是第几项功能\n",
    "\n",
    "        else:#如果输入不在有效范围内\n",
    "            print('输入非法!请输入1-5的数字')#提示正确的输入范围\n",
    "            continue#然后继续循环直到输入正确的，这是我第一次使用continue，此前并不知道这个功能\n",
    "        if func_choice=='1':#在上面的输入有效行判断中输入了有效的序号，跳出了(这个用词准确吗？)循环但并不终止程序\n",
    "            new_task=input('请录入新任务名: ')#提示输入新的任务名\n",
    "            print('是否马上开始新任务?')#提示让用户选择录入的新任务名的其实标记状态\n",
    "            start_y_n=y_n(prompt='请输入y/n',valid_choice=['y','n'])#使用选择y/n的模块\n",
    "            if start_y_n=='y':#如果选择的是'y'\n",
    "                newtask={\n",
    "                    '任务名':new_task,\n",
    "                    '状态':'进行中'\n",
    "                }#将新任务的任务名以及进行中的状态录入newtask字典\n",
    "            else:\n",
    "                newtask={\n",
    "                    '任务名':new_task,\n",
    "                    '状态':'未开始'\n",
    "                }#否则将新任务的任务名以及非开始的状态录入newtask字典\n",
    "                #在录入newtask字典时出现了两个几乎一模一样的函数功能，我考虑过是否设置成模块并调用模块，但我觉得没必要，一时只出现了两次，二是这个函数特别简单，因此放弃了单独为新增任务设置模块的想法\n",
    "            tasklist.append(newtask)#把newtask字典装入tasklist列表\n",
    "            print('新增任务完成!')#提示完成\n",
    "            pass#大循环的第一个pass，这个pass的缩进层级与while True下第一个if下的第一层缩进相同，这是我第一次使用这个功能，我理解是上一层while True输入有效数字序号后，还不允许结束程序，必须继续运行直到用户选择离开程序\n",
    "\n",
    "        elif func_choice=='2':#有效数字序号的中的选项2\n",
    "            if len(tasklist)==0:#判断tasklist是否为空，后面还将出现数次，因为语句特别简单所以没必要设置模块调用\n",
    "                print('没有可删除的任务!')#提示没有可删除的任务\n",
    "            else:\n",
    "                del_task=picktask()#把上面先被编号然后输出被选择的编号对应的任务名的字符串的模块的输出结果(这一串形容准确吗？)赋值给变量del_task\n",
    "                print(del_task)#这个打印其实没有任何必要，只是我在一开始无论怎么调试都无法用picktask()模块输出正确结果因为想看看到底这个模块输出了个什么东西而设置的打印，但我还是保留了下来，算是保留了一个思路\n",
    "                print('是否确认删除?')#提示是否确定要删除\n",
    "                del_y_n=y_n(prompt='请输入y/n',valid_choice=['y','n'])#再次使用选择y/n的模块\n",
    "                if del_y_n=='y':#如果选择y确认删除\n",
    "                    deleted_task={\n",
    "                        '任务名':del_task,\n",
    "                        '状态':'已删除'\n",
    "                    }#这里我考虑过用调取引用之类的，但我发现这个简单的直接用现成的del_task再做一个字典是最简单的方法，因为在删除任务的操作背景下，任务状态是确定的'已删除',唯一的变化因素就是现成的del_task\n",
    "                    taskdelete.append(deleted_task)#把新造的deleted_task字典装入开头设置的taskdelete列表中\n",
    "                    for dt in tasklist:#遍历tasklist中的每个字典，赋值给变量dt\n",
    "                        if del_task in dt['任务名']:#如果字典dt中以'任务名'为key的value中包含del_task(同样的问题，我觉得用==也可以)\n",
    "                            tasklist.remove(dt)#就把包含这个value的字典dt删除\n",
    "                            print('删除成功!')#然后提示删除成功\n",
    "            pass#大循环的第二个pass\n",
    "\n",
    "        elif func_choice=='3':#有效数字序号中的选项3\n",
    "            if len(tasklist)==0:\n",
    "                print('没有可查看/修改的任务!')\n",
    "            else:\n",
    "                while True:#在这里我使用了一个跟大循环逻辑几乎一模一样的循环，姑且称为中循环，因为我想让整个程序更加贴近现实的使用界面和需求\n",
    "                    print('请选择要执行的功能: ')\n",
    "                    print('1.查看任务;')\n",
    "                    print('2.标记任务;')\n",
    "                    print('3.退出功能')\n",
    "                    func_choice2=input('请输入你想执行的功能序号: ').strip()\n",
    "                    if func_choice2 in ['1','2','3']:\n",
    "                        print(f'你选择了功能{int(func_choice2)}')\n",
    "                    else:\n",
    "                        print('非法输入!请重新输入要执行的任务数字序号')\n",
    "                        continue\n",
    "\n",
    "                    if func_choice2=='1':#在选择查看任务后\n",
    "                        while True:#在这里我在同一个分支选项内嵌套了又一个循环，姑且称为中循环中的小循环，同样目的是让整个程序更加贴近现实的使用界面和需求\n",
    "                            print('请选择要你想要进一步执行的功能: ')\n",
    "                            print('1.查看全部任务;')\n",
    "                            print('2.查看已完成任务;')\n",
    "                            print('3.查看进行中的任务;')\n",
    "                            print('4.查看未开始的任务;')\n",
    "                            print('5.退出')\n",
    "                            func_choice3=input('请输入你想进一步执行的功能序号: ').strip()\n",
    "                            if func_choice3 in ['1','2','3','4','5']:\n",
    "                                print(f'你选择了功能{int(func_choice3)}')\n",
    "                            else:\n",
    "                                print('非法输入!请重新输入要执行的任务数字序号')\n",
    "                            if func_choice3=='1':\n",
    "                                print('请查看全部任务: ')\n",
    "                                for a in tasklist:\n",
    "                                    print(a)\n",
    "                                pass\n",
    "                            elif func_choice3=='2':\n",
    "                                check('已完成')\n",
    "                                pass\n",
    "\n",
    "                            elif func_choice3=='3':\n",
    "                                check('进行中')\n",
    "                                pass\n",
    "                            elif func_choice3=='4':\n",
    "                                check('待开始')\n",
    "                                pass#这些pass是小循环中能顺利执行完毕的命令\n",
    "                            else:\n",
    "                                print('感谢!')\n",
    "                                break#在这个小循环中，我预算设置的可以打印不同标记状态的任务清单的模块被调用，可以看到上面每一个check()括号中的参数都不同，能快速获取我想要结果，这非常实用\n",
    "                        \n",
    "                        pass#这是中循环中的第一个pass\n",
    "                            \n",
    "\n",
    "                    if func_choice2=='2':#选择标记任务后\n",
    "                        change_task=picktask()#第二次调用先被编号然后输出被选择的编号对应的任务名的字符串的模块的输出结果赋值给变量change_task\n",
    "                        print(change_task)#这个打印同样没意义，也是我调试picktask()模块时测试使用的，思路的一种保留\n",
    "                        for tn in tasklist:#遍历tasklist中的字典并把这些字典逐一赋值给变量tn\n",
    "                            if tn['任务名']==change_task:#这里我用了==，我也不知道为什么我用了==，我现在觉得用if change_task in tn['任务名']好像也是可以的\n",
    "                                print(f\"{change_task}现在的状态为{tn['状态']}\")#先给用户看名为change_task的任务的现有状态，因为考虑到这个功能里只显示任务名，任务状态不直观，有可能用户选择了这个任务但又改主意了\n",
    "                                \n",
    "                                status_list=['已完成','进行中','待开始']#这里对我来说是一个巨大的难点，我在写这个程序的结构图的时候想尽可能地人性化，因为让用户输入任务名才能改任务状态的做法太不符合实际，我并不想为了写代码而写代码，用户操作的友好性是一定会面对的问题\n",
    "                                status_choice=[x for x in status_list if x != tn['状态']]#这一步我请教了chatgpt，我忘记了可以这样将我不想要的任务状态以变量的形式排除，从而形成一个动态的status_choice列表\n",
    "                                print('请选择修改后的状态:')#提示用户进行任务修改后状态的选择\n",
    "                                for i, n in enumerate(status_choice,start=1):#幸亏此前练习过enumerate函数，我只能想到使用它帮助我实现这个功能，让它给status_choice中的两个(肯定是两个，三排除一剩二)状态编号，至于编号谁先谁后或者到底谁在列表中就不重要了，最终由用户交互界面来选择，这一点还是挺神奇的，在程序跑通前我就有这种感知，可见写程序的人对程序也并不只100%掌控，当然程序的执行方向是一定要掌控的\n",
    "                                    print(f'{i}.{n}')#把'薛定谔的n'及其编号打印出来给用户看\n",
    "                                while True:#遇到break之前将一直循环，我一开始犯了一个错，把这个while True放到了for的缩进下，会导致只遍历并编码一个n之后就开始执行while True循环，这是一个非常有价值的逻辑错误！\n",
    "                                    change_choice=input('你的选择是: ')#要求选择修改后的状态对应的数字序号\n",
    "                                    if change_choice in ['1','2']:#这里我笃定只有两个选项，所以把范围设置为固定的['1','2'],如果有不确定数量的n,我会考虑用上面在pickname()模块中使用过的方法，用len和range以及int转变数字序号格式的形式来确保有效性\n",
    "                                        tn['状态']=status_choice[int(change_choice)-1]#这里一开始我疏忽了列表索引应该-1,这是个不应该的错误\n",
    "                                        print('状态已更新!')#提示状态已更新\n",
    "                                        break#结束循环\n",
    "                                    else:\n",
    "                                        print('无效输入!请输入有效数值')\n",
    "                                        continue#无效则继续执行循环\n",
    "\n",
    "                        pass#中循环的第二个pass\n",
    "                    if func_choice2=='3':\n",
    "                        print('谢谢使用!')\n",
    "                        break#中循环的break\n",
    "            pass#大循环的第三个pass\n",
    "\n",
    "        elif func_choice=='4':\n",
    "            if len(taskdelete)==0:\n",
    "                print('没有可查看的任务!')\n",
    "            else:\n",
    "                print('请查阅已删除的任务')\n",
    "                for a in taskdelete:\n",
    "                    print(a)\n",
    "            pass#大循环的第四个pass\n",
    "\n",
    "        else:\n",
    "            print('感谢使用!')\n",
    "            break#没有需要pass的了，break\n",
    "                                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b3897f4-88b9-4dfe-8ccf-4c2f1d98f7b0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
